home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / ftools.rb < prev    next >
Text File  |  2007-02-12  |  6KB  |  262 lines

  1. # = ftools.rb: Extra tools for the File class
  2. #
  3. # Author:: WATANABE, Hirofumi
  4. # Documentation:: Zachary Landau
  5. #
  6. # This library can be distributed under the terms of the Ruby license.
  7. # You can freely distribute/modify this library.
  8. #
  9. # It is included in the Ruby standard library.
  10. #
  11. # == Description
  12. #
  13. # ftools adds several (class, not instance) methods to the File class, for
  14. # copying, moving, deleting, installing, and comparing files, as well as
  15. # creating a directory path.  See the File class for details.
  16. #
  17. # FileUtils contains all or nearly all the same functionality and more, and
  18. # is a recommended option over ftools 
  19. #
  20. # When you
  21. #
  22. #   require 'ftools'
  23. #
  24. # then the File class aquires some utility methods for copying, moving, and
  25. # deleting files, and more.
  26. #
  27. # See the method descriptions below, and consider using FileUtils as it is
  28. # more comprehensive.
  29. #
  30. class File
  31. end
  32.  
  33. class << File
  34.  
  35.   BUFSIZE = 8 * 1024
  36.  
  37.   #
  38.   # If +to+ is a valid directory, +from+ will be appended to +to+, adding
  39.   # and escaping backslashes as necessary. Otherwise, +to+ will be returned.
  40.   # Useful for appending +from+ to +to+ only if the filename was not specified
  41.   # in +to+. 
  42.   #
  43.   def catname(from, to)
  44.     if directory? to
  45.       join to.sub(%r([/\\]$), ''), basename(from)
  46.     else
  47.       to
  48.     end
  49.   end
  50.  
  51.   #
  52.   # Copies a file +from+ to +to+. If +to+ is a directory, copies +from+
  53.   # to <tt>to/from</tt>.
  54.   #
  55.   def syscopy(from, to)
  56.     to = catname(from, to)
  57.  
  58.     fmode = stat(from).mode
  59.     tpath = to
  60.     not_exist = !exist?(tpath)
  61.  
  62.     from = open(from, "rb")
  63.     to = open(to, "wb")
  64.  
  65.     begin
  66.       while true
  67.     to.syswrite from.sysread(BUFSIZE)
  68.       end
  69.     rescue EOFError
  70.       ret = true
  71.     rescue
  72.       ret = false
  73.     ensure
  74.       to.close
  75.       from.close
  76.     end
  77.     chmod(fmode, tpath) if not_exist
  78.     ret
  79.   end
  80.  
  81.   #
  82.   # Copies a file +from+ to +to+ using #syscopy. If +to+ is a directory,
  83.   # copies +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from -> to</tt>
  84.   # is printed.
  85.   #
  86.   def copy(from, to, verbose = false)
  87.     $stderr.print from, " -> ", catname(from, to), "\n" if verbose
  88.     syscopy from, to
  89.   end
  90.  
  91.   alias cp copy
  92.  
  93.   #
  94.   # Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory,
  95.   # copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from ->
  96.   # to</tt> is printed.
  97.   #
  98.   def move(from, to, verbose = false)
  99.     to = catname(from, to)
  100.     $stderr.print from, " -> ", to, "\n" if verbose
  101.  
  102.     if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and file? to
  103.       unlink to
  104.     end
  105.     fstat = stat(from)
  106.     begin
  107.       rename from, to
  108.     rescue
  109.       begin
  110.         symlink readlink(from), to and unlink from
  111.       rescue
  112.     from_stat = stat(from)
  113.     syscopy from, to and unlink from
  114.     utime(from_stat.atime, from_stat.mtime, to)
  115.     begin
  116.       chown(fstat.uid, fstat.gid, to)
  117.     rescue
  118.     end
  119.       end
  120.     end
  121.   end
  122.  
  123.   alias mv move
  124.  
  125.   #
  126.   # Returns +true+ if and only if the contents of files +from+ and +to+ are
  127.   # identical. If +verbose+ is +true+, <tt>from <=> to</tt> is printed.
  128.   #
  129.   def compare(from, to, verbose = false)
  130.     $stderr.print from, " <=> ", to, "\n" if verbose
  131.  
  132.     return false if stat(from).size != stat(to).size
  133.  
  134.     from = open(from, "rb")
  135.     to = open(to, "rb")
  136.  
  137.     ret = false
  138.     fr = tr = ''
  139.  
  140.     begin
  141.       while fr == tr
  142.     fr = from.read(BUFSIZE)
  143.     if fr
  144.       tr = to.read(fr.size)
  145.     else
  146.       ret = to.read(BUFSIZE)
  147.       ret = !ret || ret.length == 0
  148.       break
  149.     end
  150.       end
  151.     rescue
  152.       ret = false
  153.     ensure
  154.       to.close
  155.       from.close
  156.     end
  157.     ret
  158.   end
  159.  
  160.   alias cmp compare
  161.  
  162.   #
  163.   # Removes a list of files. Each parameter should be the name of the file to
  164.   # delete. If the last parameter isn't a String, verbose mode will be enabled.
  165.   # Returns the number of files deleted.
  166.   #
  167.   def safe_unlink(*files)
  168.     verbose = if files[-1].is_a? String then false else files.pop end
  169.     files.each do |file|
  170.       begin
  171.         unlink file
  172.         $stderr.print "removing ", file, "\n" if verbose
  173.       rescue Errno::EACCES # for Windows
  174.         continue if symlink? file
  175.         begin
  176.           mode = stat(file).mode
  177.           o_chmod mode | 0200, file
  178.           unlink file
  179.           $stderr.print "removing ", file, "\n" if verbose
  180.         rescue
  181.           o_chmod mode, file rescue nil
  182.         end
  183.       rescue
  184.       end
  185.     end
  186.   end
  187.  
  188.   alias rm_f safe_unlink
  189.  
  190.   #
  191.   # Creates a directory and all its parent directories.
  192.   # For example,
  193.   #
  194.   #    File.makedirs '/usr/lib/ruby'
  195.   #
  196.   # causes the following directories to be made, if they do not exist.
  197.   #    * /usr
  198.   #    * /usr/lib
  199.   #    * /usr/lib/ruby
  200.   #
  201.   # You can pass several directories, each as a parameter. If the last
  202.   # parameter isn't a String, verbose mode will be enabled.
  203.   #
  204.   def makedirs(*dirs)
  205.     verbose = if dirs[-1].is_a? String then false else dirs.pop end
  206.     mode = 0755
  207.     for dir in dirs
  208.       parent = dirname(dir)
  209.       next if parent == dir or directory? dir
  210.       makedirs parent unless directory? parent
  211.       $stderr.print "mkdir ", dir, "\n" if verbose
  212.       if basename(dir) != ""
  213.         begin
  214.           Dir.mkdir dir, mode
  215.         rescue SystemCallError
  216.           raise unless directory? dir
  217.         end
  218.       end
  219.     end
  220.   end
  221.  
  222.   alias mkpath makedirs
  223.  
  224.   alias o_chmod chmod
  225.  
  226.   vsave, $VERBOSE = $VERBOSE, false
  227.  
  228.   #
  229.   # Changes permission bits on +files+ to the bit pattern represented
  230.   # by +mode+. If the last parameter isn't a String, verbose mode will
  231.   # be enabled.
  232.   #
  233.   #   File.chmod 0755, 'somecommand'
  234.   #   File.chmod 0644, 'my.rb', 'your.rb', true
  235.   #
  236.   def chmod(mode, *files)
  237.     verbose = if files[-1].is_a? String then false else files.pop end
  238.     $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
  239.     o_chmod mode, *files
  240.   end
  241.   $VERBOSE = vsave
  242.  
  243.   #
  244.   # If +src+ is not the same as +dest+, copies it and changes the permission
  245.   # mode to +mode+. If +dest+ is a directory, destination is <tt>dest/src</tt>.
  246.   # If +mode+ is not set, default is used. If +verbose+ is set to true, the
  247.   # name of each file copied will be printed.
  248.   #
  249.   def install(from, to, mode = nil, verbose = false)
  250.     to = catname(from, to)
  251.     unless exist? to and cmp from, to
  252.       safe_unlink to if exist? to
  253.       cp from, to, verbose
  254.       chmod mode, to, verbose if mode
  255.     end
  256.   end
  257.  
  258. end
  259.  
  260. # vi:set sw=2:
  261.